using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

using WeifenLuo.WinFormsUI.Docking;
using System.IO;

using SBW.Utils;

namespace Athena
{
    public partial class MainForm : Form
    {
        Preferences _oPreferences = new Preferences();
        private SBWMenu _sbwMenu;


        internal void ParseCommandLine(string[] args)
        {
            // for now just open the given models
            for (int i = 0; i < args.Length; i++)
            {
                if (File.Exists(args[i]))
                {
                    Program.Model.OpenModel(args[i]);
                }
            }
        }

        ToolStripMenuItem oCurrentSelection;

        public MainForm()
        {
            InitializeComponent();

            dockPanel.DocumentStyle = DocumentStyle.DockingSdi;
            drawPanel1.Show(dockPanel, DockState.Document);

            oCurrentSelection = new ToolStripMenuItem("Selected");
            mnuMain.Items.Insert(mnuMain.Items.Count - 1, oCurrentSelection);

            _sbwMenu = new SBWMenu(mnuSBW, "Athena", delegate
                                                      {
                                                          return Utility.GetSBML();
                                                      });         

            PluginManager.Instance.PluginsChanged += new PluginManager.PluginsChangedDelegate(Instance_PluginsChanged);

            this.Load+=new EventHandler(MainForm_Load);

        }
        public MainForm(string[] args) : this()
        {
            // This causes trouble on my machine ... opening of files should not happen in the constructor, but rather later, 
            // when the form is displayed.
            // ParseCommandLine(args);
        }

        void Instance_PluginsChanged(object sender, EventArgs e)
        {
            this.toolStripContainer1.SuspendLayout();
            toolStrip2.SuspendLayout();

            this.toolStripContainer1.TopToolStripPanel.Controls.Clear();
            toolStrip2.Items.Clear();

            Utility.SetupToolWindow(toolStrip2);
            this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1);

            ToolManager.Instance.ToolStripContainer = this.toolStripContainer1;
            ToolManager.Instance.ToolStripMenu = toolStrip2;
            ToolManager.Instance.DockPanel = dockPanel;
            ToolManager.Instance.SetupPluginsMenu(pluginsToolStripMenuItem);
            ToolManager.Instance.SetupSimulatorMenu(simulatorsToolStripMenuItem);
            this.toolStripContainer1.ResumeLayout();
            toolStrip2.ResumeLayout();
        }

        private void newToolStripButton_Click(object sender, EventArgs e)
        {
            Utility.DrawPanel.NewDocument();
            Utility.Refresh();
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                Program.Model.OpenModel(openFileDialog1.FileName);
            }
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(Program.Model.DefaultFileName))
            {
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    Program.Model.SaveModel(saveFileDialog1.FileName);
                }
            }
            else
            {
                Program.Model.SaveModel(Program.Model.DefaultFileName);
            }
        }

        private void printToolStripButton_Click(object sender, EventArgs e)
        {
            if (printDialog1.ShowDialog() == DialogResult.OK)
            {
                printDocument1.PrinterSettings = printDialog1.PrinterSettings;
                printDocument1.Print();
            }
        }

        private void cutToolStripButton_Click(object sender, EventArgs e)
        {
            Utility.DrawPanel.Cut();
        }

        private void copyToolStripButton_Click(object sender, EventArgs e)
        {
            Utility.DrawPanel.Copy();
        }

        private void pasteToolStripButton_Click(object sender, EventArgs e)
        {
            Utility.DrawPanel.Paste();
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {

            //
            // TODO: Think more about scaling, should probably preserve aspect ratio

            //RectangleF oBounds = DrawPanel.GetBounds();

            //Matrix oTransform = new Matrix();

            //oTransform.Scale(
            //    e.MarginBounds.Width / oBounds.Width,
            //    e.MarginBounds.Height / oBounds.Height, MatrixOrder.Prepend);
            //oTransform.Translate(e.MarginBounds.X - oBounds.X * e.MarginBounds.Width / oBounds.Width,
            //    e.MarginBounds.Y - oBounds.Y * e.MarginBounds.Height / oBounds.Height, MatrixOrder.Append);

            //e.Graphics.Transform = oTransform;
            e.Graphics.SmoothingMode = SmoothingMode.None;
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
            //e.Graphics.
            //e.Graphics.DpiX = 1200;
            //e.Graphics.DpiY = 1200;

            Utility.DrawPanel.pnlCanvas.RenderCanvas(e.Graphics, false);
        }

        private void toolAlignLeft_Click(object sender, EventArgs e)
        {
            Utility.AlignLeft(Program.Model.Selected);
            drawPanel1.Invalidate();
        }

        private void toolStripButtonRedo_Click(object sender, EventArgs e)
        {
            HistoryManager.History.Redo();
        }

        private void toolStripButtonUndo_Click(object sender, EventArgs e)
        {
            HistoryManager.History.Undo();
        }
        void toolStripZoom_TextChanged(object sender, System.EventArgs e)
        {
            string sZoom = toolStripZoom.Text;
            //if (toolStripZoom.SelectedIndex >= 0)
            //{
            //    sZoom = (string)toolStripZoom.SelectedItem;
            //}
            try
            {
                float dValue = 0;
                if (sZoom.IndexOf('%') >= 0)
                {
                    dValue = Convert.ToSingle(sZoom.Substring(0, sZoom.IndexOf('%')));
                    dValue /= 100f;
                }
                else
                {
                    dValue = Convert.ToSingle(sZoom);
                }
                if (dValue > 0)
                {
                    //GetPanel().pnlCanvas.Reset();
                    Utility.DrawPanel.pnlCanvas.ScaleFactor = dValue;
                    Utility.Refresh();
                    Utility.GetPanel().Focus();
                }
            }
            catch (Exception)
            {
                switch (sZoom.ToUpper())
                {
                    case "FIT":
                        Utility.DrawPanel.pnlCanvas.FitToView();
                        Utility.GetPanel().Focus();
                        break;
                    case "FIT SELECTED":
                        Utility.DrawPanel.pnlCanvas.FitToView(Program.Model.Selected);
                        Utility.GetPanel().Focus();
                        break;
                    default:
                        break;
                }
            }
        }

        void helpToolStripButton_Click(object sender, System.EventArgs e)
        {
            AboutBox1 oBox = new AboutBox1();
            oBox.ShowDialog();
        }
        /*
        private void MainForm_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] sFilenames = (string[])e.Data.GetData(DataFormats.FileDrop);
                FileInfo oInfo = new FileInfo(sFilenames[0]);
                if (oInfo.Extension.ToLower() == ".dll" || oInfo.Extension.ToLower() == ".veb")
                {
                    e.Effect = DragDropEffects.Copy;
                    return;
                }
            }
            e.Effect = DragDropEffects.None;

        }
        
        private void MainForm_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    string[] sFilenames = (string[])e.Data.GetData(DataFormats.FileDrop);
                    for (int i = 0; i < sFilenames.Length; i++)
                    {
                        string sCurrentFile = sFilenames[i];
                        FileInfo oInfo = new FileInfo(sCurrentFile);
                        switch (oInfo.Extension.ToLower())
                        {
                            case ".dll":
                                try
                                {
                                    PluginManager.Instance.AddPluginsFromFile(sCurrentFile);
                                }
                                catch (Exception )
                                {

                                }
                                break;
                            case ".veb":
                                try
                                {
                                    Program.Model.OpenModel(sCurrentFile);
                                }
                                catch (Exception )
                                {

                                }
                                break;
                        }

                    }
                }
            }
            catch (Exception)
            {
                /// nevermind
            }

        }
        */
        public static System.ComponentModel.ComponentResourceManager Resources
        {
            get
            {
                return new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            }
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Program.Model.SelectAllItems();
            Utility.Refresh();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            _sbwMenu.UpdateSBWMenu();            

            // add tools that are not done yet
            Utility.SetupToolWindow(toolStrip2);

            ToolManager.Instance.SelectedMenu = oCurrentSelection;

            ToolManager.Instance.ToolStripContainer = this.toolStripContainer1;
            ToolManager.Instance.ToolStripMenu = toolStrip2;
            ToolManager.Instance.DockPanel = dockPanel;
            //ToolManager.Instance.SetupPluginsMenu(pluginsToolStripMenuItem);
            //ToolManager.Instance.SetupSimulatorMenu(simulatorsToolStripMenuItem);
           
            //TODO: this should probably be the directory where the assembly is, should it not?
            PluginManager.Instance.AddPluginsFromDirectory(Utility.CurrentDirectory + "\\plugins");

        }

        

        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _oPreferences.ShowDialog();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            toolStripMenuItem1.Checked = !toolStripMenuItem1.Checked;
            Utility.ShowToolTip = toolStripMenuItem1.Checked;
        }

        private void saveAsToolStripButton_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                Program.Model.SaveModel(saveFileDialog1.FileName);
            }
        }
    }
}